package cn.fuxi2022.accounts.menu.service.impl;

import cn.fuxi2022.accounts.menu.service.AccountsMenuService;
import cn.fuxi2022.accounts.menu.service.WeChatMenuService;
import cn.fuxi2022.accounts.properties.ConstantPropertiesUtil;
import cn.fuxi2022.accounts.properties.WeChatAppletsProperties;
import cn.fuxi2022.core.exception.SmartGroupException;
import cn.fuxi2022.core.utils.HttpClientUtils;
import cn.fuxi2022.model.empty.accounts.AccountsMenu;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;

@Service
public class WeChatMenuServiceImpl implements WeChatMenuService {

    @Autowired
    private AccountsMenuService accountsMenuService;

    @Autowired
    private WxMpService wxMpService;


    @Override
    public String getAccessToken() {
        // 1.拼接请求地址
        String url = String.format(TOKEN_URL, ConstantPropertiesUtil.ACCESS_KEY_ID, ConstantPropertiesUtil.ACCESS_KEY_SECRET);

        // 2.发送请求
        String weChatResponse;
        try {
            weChatResponse = HttpClientUtils.get(url);
        } catch (Exception e) {

            throw new SmartGroupException("获取access_token失败");
        }

        // 3.解析结果，获取AccessToken
        JSONObject weChatObj = JSONObject.parseObject(weChatResponse);
        Object token = weChatObj.get("access_token");

        // 4.判断是否获取成功，获取为空就返回null
        if (ObjectUtils.isEmpty(token)) {
            return null;
        }

        return (String) token;
    }

    /**
     * 说明：
     * 自定义菜单最多包括3个一级菜单，每个一级菜单最多包含5个二级菜单。
     * 一级菜单最多4个汉字，二级菜单最多8个汉字，多出来的部分将会以“...”代替。
     * 创建自定义菜单后，菜单的刷新策略是，在用户进入公众号会话页或公众号profile页时，
     * 如果发现上一次拉取菜单的请求在5分钟以前，就会拉取一下菜单，如果菜单有更新，就会刷新客户端的菜单。
     * 测试时可以尝试取消关注公众账号后再次关注，则可以看到创建后的效果。
     */
    @Override
    public void syncMenu() {
        // 1.获取微信菜单的JSON
        JSONObject menuJson = getMenuJson();
        // 2.将JSON发送至微信服务器
        // 获取菜单相关操作接口
        try {
            wxMpService.getMenuService().menuCreate(String.valueOf(menuJson));
        } catch (WxErrorException e) {
            e.printStackTrace();
            throw new SmartGroupException("同步微信菜单失败");
        }
    }

    @Override
    public void removeMenu() {
        // 删除微信自定义菜单
        try {
            wxMpService.getMenuService().menuDelete();
        } catch (WxErrorException e) {
            e.printStackTrace();
            throw new SmartGroupException("删除微信菜单失败");
        }
    }

    /**
     * 将当前数据库的菜单转化为微信菜单指定的JSON
     *
     * @return 微信菜单指定的JSON
     */
    private JSONObject getMenuJson() {
        // 1.获取菜单列表
        List<AccountsMenu> list = accountsMenuService.getAllList();

        // 2.封装菜单数组
        JSONArray array = new JSONArray();

        // 3.循环一级菜单
        for (AccountsMenu menuVo : list) {
            // A.创建一级菜单JSON对象
            JSONObject oneMenu = new JSONObject();
            // B.将遍历的一级菜单名称放入
            oneMenu.put("name", menuVo.getMenuName());
            // C.封装sub_button的二级菜单
            JSONArray subButton = new JSONArray();
            oneMenu.put("sub_button", subButton);
            // D.如果当前菜单的key不为空，将遍历的key放入
            if (StringUtils.hasText(menuVo.getMenuKey())) {
                oneMenu.put("key", menuVo.getMenuKey());
            }

            // 4.遍历当前一级菜单的二级菜单
            for (AccountsMenu menuTwoVo : menuVo.getChildren()) {
                JSONObject twoMenu = new JSONObject();
                // A.将遍历的二级菜单名称放入
                twoMenu.put("name", menuTwoVo.getMenuName());
                // B.将遍历的类型放入
                twoMenu.put("type", menuTwoVo.getType());
                // C.根据类型判断是否还需要添加属性
                // 如果是 view 类型，还需要添加url
                if ("view".equals(menuTwoVo.getType())) {
                    twoMenu.put("url", menuTwoVo.getUrl());
                }
                // 如果是 miniprogram 类型，说明需要跳转小程序
                if ("miniprogram".equals(menuTwoVo.getType())) {
                    twoMenu.put("url", "http://mp.weixin.qq.com");
                    twoMenu.put("appid", WeChatAppletsProperties.APP_ID);
                    twoMenu.put("pagepath",menuTwoVo.getUrl());
                }
                // D.如果当前菜单的key不为空，将遍历的key放入
                if (StringUtils.hasText(menuTwoVo.getMenuKey())) {
                    twoMenu.put("key", menuTwoVo.getMenuKey());
                }
                // E.将当前封装好的二级菜单加入一级菜单数组
                subButton.add(twoMenu);
            }

            // E.将当前封装好的一级菜单加入菜单数组
            array.add(oneMenu);
        }

        // 4.封装外层的button
        JSONObject menuObj = new JSONObject();
        menuObj.put("button", array);
        return menuObj;
    }
}
